package com.retail.bbq.cola.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.PropertyNamingStrategy;
import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.serializer.SerializeConfig;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

import com.retail.bbq.cola.enums.ErrorCodeEnum;
import com.retail.bbq.cola.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.*;
import org.springframework.lang.Nullable;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

@Configuration
@Slf4j
public class RestUtils {

    public static final RestTemplate restTemplate = new RestTemplate();


    public static JSONObject get(String url, Map<String, String> urlParams) {
        return get(urlToUri(url, urlParams));
    }

    //在处理企业微信某些参数时有问题
    public static JSONObject get(String url) {
        return get(URI.create(url));
    }

    private static JSONObject get(URI uri) {
        ResponseEntity<JSONObject> responseEntity = restTemplate.getForEntity(uri, JSONObject.class);
      //  serverIsRight(responseEntity);   //判断服务器返回状态码
        return responseEntity.getBody();
    }


    private static JSONObject post(URI uri, JSONObject json) {
        //组装url
        //设置提交json格式数据
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity<JSONObject> request = new HttpEntity(json, headers);
        ResponseEntity<JSONObject> responseEntity = restTemplate.postForEntity(uri, request, JSONObject.class);
        serverIsRight(responseEntity);  //判断服务器返回状态码
        return responseEntity.getBody();
    }

    private static Object post(URI uri, Object param, Class responseClass) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        HttpEntity request = new HttpEntity(param, headers);
        ResponseEntity responseEntity = restTemplate.postForEntity(uri, request, responseClass);


        serverIsRight(responseEntity);
        return responseEntity.getBody();

    }

    private static URI urlToUri(String url, Map<String, String> urlParams) {
        //设置提交json格式数据
        UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url);
        for (Map.Entry<String, String> entry : urlParams.entrySet()) {
            uriBuilder.queryParam(entry.getKey(), entry.getValue());
        }
        return uriBuilder.build(true).toUri();
    }


    private static void serverIsRight(ResponseEntity responseEntity) {

        if (!Objects.equals(responseEntity.getStatusCodeValue(), 200)) {
            log.info("企业微信服务器请求异常:{}", responseEntity.getStatusCodeValue());
        }

    }

    public static <T> T post(String url, @Nullable Object param, Class<T> responseType) {
        if (Objects.isNull(param)) {
            throw new BusinessException(ErrorCodeEnum.PARAM_ERROR);
        }
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        SerializeConfig config = new SerializeConfig();
        config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
        Map<String, Object> paramMap = JSON.parseObject(JSON.toJSONString(param, config), new TypeReference<HashMap<String, Object>>() {
        });
        HttpEntity<Map<String, Object>> request = new HttpEntity<>(paramMap, headers);
        log.info("request:{}", JSON.toJSONString(request));
        JSONObject response = restTemplate.postForObject(url, request, JSONObject.class);

        return JSON.parseObject(JSON.toJSONString(response, config), responseType);
    }
    public static <T> T postForForm(String url, @Nullable Object param, Class<T> responseType) {
        if (Objects.isNull(param)) {
            throw new BusinessException(ErrorCodeEnum.PARAM_ERROR);
        }
        ResponseEntity response = restTemplate.postForEntity(url, new HttpEntity(param, new HttpHeaders()), responseType);
        return JSON.parseObject(JSON.toJSONString(response.getBody()), responseType);
    }

    public static <T> T post(String url, @Nullable Object param, Class<T> responseType, MediaType type) {
        if (Objects.isNull(param)) {
            throw new BusinessException(ErrorCodeEnum.PARAM_ERROR);
        }
        HttpHeaders headers = new HttpHeaders();
        //headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        headers.setContentType(type);
        SerializeConfig config = new SerializeConfig();
        config.propertyNamingStrategy = PropertyNamingStrategy.SnakeCase;
        Map<String, Object> paramMap = JSON.parseObject(JSON.toJSONString(param, config), new TypeReference<HashMap<String, Object>>() {
        });
        MultiValueMap<String,Object> params = new LinkedMultiValueMap<>();
        paramMap.forEach(params::add);
        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(params, headers);
        log.info("request:{}", JSON.toJSONString(request));
        JSONObject response = restTemplate.postForObject(url, request, JSONObject.class);
        log.info("response:{}", JSON.toJSONString(response));
        return JSON.parseObject(JSON.toJSONString(response, config), responseType);
    }


}
